package com.ape.mapsa.dao;

import java.io.Serializable;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.ape.mapsa.model.Notification;
import com.ape.mapsa.model.Role;
import com.ape.mapsa.model.User;
import com.ape.mapsa.model.UserRole;

@Repository(value = "userDAO")
@Transactional
public class UserDAO implements IUserDAO, Serializable {
	private static final Logger log = Logger.getLogger(UserDAO.class);
	private static final long serialVersionUID = -766065143281358649L;

	private SessionFactory sessionFactory;

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	/**
	 * Add User
	 * 
	 * @param User
	 *            user
	 */
	@Override
	public void addUser(User user) {
		sessionFactory.getCurrentSession().save(user);
	}

	/**
	 * Delete User
	 * 
	 * @param User
	 *            user
	 */
	@Override
	public void deleteUser(User user) {
		sessionFactory.getCurrentSession().delete(user);
	}

	/**
	 * Update User
	 * 
	 * @param User
	 *            user
	 */
	@Override
	public void updateUser(User user) {
		try {
			sessionFactory.getCurrentSession().update(user);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Get User
	 * 
	 * @param int User Id
	 * @return User
	 */
	@Override
	public User getUserByEmail(String email) {
		@SuppressWarnings("unchecked")
		List<User> list = sessionFactory.getCurrentSession().createCriteria(User.class).add(Restrictions.eq("email", email)).list();
		if (!list.isEmpty()) {
			return (User) list.get(0);
		} else {
			return null;
		}
	}

	/**
	 * Get User List
	 * 
	 * @return List - User list
	 */
	@Override
	public List<User> getUsers() {
		@SuppressWarnings("unchecked")
		List<User> list = sessionFactory.getCurrentSession().createQuery("from User").list();
		return list;
	}

	@Override
	public List<Role> getAllRoles() {
		@SuppressWarnings("unchecked")
		List<Role> list = sessionFactory.getCurrentSession().createQuery("from Role").list();
		return list;
	}

	@Override
	public List<UserRole> getAllUserRoles(User user) {
		Query createQuery = sessionFactory.getCurrentSession().createQuery("from UserRole where email=?");
		createQuery.setParameter(0, user.getEmail());
		@SuppressWarnings("unchecked")
		List<UserRole> list = createQuery.list();
		return list;
	}

	@Override
	@Transactional(readOnly = false)
	public void removeUserRoles(User selectedUser) {
		try {
			Session session = sessionFactory.getCurrentSession();
			for (UserRole ur : selectedUser.getRoles()) {
				session.delete(ur);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public User getUserById(Long id) {
		@SuppressWarnings("unchecked")
		List<User> list = sessionFactory.getCurrentSession().createQuery("from User where id=?").setParameter(0, id).list();
		if (!list.isEmpty()) {
			return (User) list.get(0);
		} else {
			return null;
		}
	}

	@Override
	public void addSession(com.ape.mapsa.model.Session session) {
		sessionFactory.getCurrentSession().save(session);
	}

	@Override
	public com.ape.mapsa.model.Session getSessionById(String id) {
		Query createQuery = sessionFactory.getCurrentSession().createQuery("from Session where sessionId=?");
		createQuery.setString(0, id);
		com.ape.mapsa.model.Session currentSession = (com.ape.mapsa.model.Session) createQuery.uniqueResult();
		return currentSession;
	}

	@Override
	public void updateSession(com.ape.mapsa.model.Session session) {
		sessionFactory.getCurrentSession().update(session);
	}

	@Override
	public List<Notification> getNotificationByRole(Role role) {
		Query query = sessionFactory.getCurrentSession().createQuery("from Notification where role_name = ?");
		query.setParameter(0, role.getRoleName());
		@SuppressWarnings("unchecked")
		List<Notification> list = query.list();
		return list;
	}

	@Override
	public void deleteNotification(Notification notification) {
		sessionFactory.getCurrentSession().delete("Notification", notification);
	}

	@Override
	public void createNotification(Notification notification) {
		sessionFactory.getCurrentSession().save("Notification", notification);
	}
}
